home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
SGI Developer Toolbox 6.1
/
SGI Developer Toolbox 6.1 - Disc 4.iso
/
public
/
bit
/
src
/
forms
/
FORMS
/
positioner.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-08-01
|
5KB
|
188 lines
/*
* positioner.c
*
* Forms Object class: POSITIONER
*
* Written by: Mark Overmars
*
* Version 2.1 a
* Date: Nov 6, 1992
*/
#include <malloc.h>
#include "gl/gl.h"
#include <sys/types.h>
#include "forms.h"
/* The special information for positioners. */
typedef struct {
float xmin, ymin; /* minimal values */
float xmax, ymax; /* maximal values */
float xval, yval; /* current values */
float xstep, ystep; /* step size to which values are rounded */
int always; /* whether always returning value */
} SPEC;
static float flinear(float val, float smin, float smax, float gmin, float gmax)
/* performs linear interpolation */
{
if (smin == smax) return gmax;
else return gmin + (gmax - gmin) * (val - smin) / (smax - smin);
}
static void draw_positioner(FL_OBJECT *ob)
/* Draws a positioner */
{
SPEC *sp = ((SPEC *)(ob->spec));
float x1 = ob->x + FL_POSITIONER_BW + 1.0;
float y1 = ob->y + FL_POSITIONER_BW + 1.0;
float w1 = ob->w - 2.0 * FL_POSITIONER_BW - 2.0;
float h1 = ob->h - 2.0 * FL_POSITIONER_BW - 2.0;
float xx,yy;
xx = flinear(sp->xval, sp->xmin, sp->xmax,x1,x1+w1-1.0);
yy = flinear(sp->yval, sp->ymin, sp->ymax,y1,y1+h1-1.0);
fl_drw_box(ob->boxtype,ob->x,ob->y,ob->w,ob->h,ob->col1,FL_POSITIONER_BW);
fl_drw_text_beside(ob->align,ob->x,ob->y,ob->w,ob->h,
ob->lcol,ob->lsize,ob->lstyle,ob->label);
fl_line(x1,yy,w1,1.0,ob->col2);
fl_line(xx,y1,1.0,h1,ob->col2);
}
static int handle_mouse(FL_OBJECT *ob,float mx,float my)
/* Handle a mouse position change */
{
SPEC *sp = ((SPEC *)(ob->spec));
float x1 = ob->x + FL_POSITIONER_BW + 1.0;
float y1 = ob->y + FL_POSITIONER_BW + 1.0;
float w1 = ob->w - 2.0 * FL_POSITIONER_BW - 2.0;
float h1 = ob->h - 2.0 * FL_POSITIONER_BW - 2.0;
float oldx = sp->xval, oldy = sp->yval;
sp->xval = flinear(mx, x1, x1+w1-1.0, sp->xmin, sp->xmax);
sp->yval = flinear(my, y1, y1+h1-1.0, sp->ymin, sp->ymax);
if (sp->xstep != 0.0) sp->xval = (int) (sp->xval/sp->xstep +0.5) * sp->xstep;
if (sp->ystep != 0.0) sp->yval = (int) (sp->yval/sp->ystep +0.5) * sp->ystep;
if (sp->xval < sp->xmin) sp->xval = sp->xmin;
if (sp->xval > sp->xmax) sp->xval = sp->xmax;
if (sp->yval < sp->ymin) sp->yval = sp->ymin;
if (sp->yval > sp->ymax) sp->yval = sp->ymax;
if (sp->xval != oldx || sp->yval != oldy)
{ fl_redraw_object(ob); return 1; }
else
{ return 0; }
}
static int handle_positioner(FL_OBJECT *ob,int event,float mx,float my,char key)
/* Handles an event */
{
SPEC *sp = (SPEC *) ob->spec;
switch (event)
{
case FL_DRAW:
draw_positioner(ob);
return 0;
case FL_PUSH:
case FL_MOUSE:
return ( handle_mouse(ob,mx,my) && sp->always);
case FL_RELEASE:
return (! sp->always);
case FL_FREEMEM:
free(ob->spec);
return 0;
}
return 0;
}
/*------------------------------*/
FL_OBJECT *fl_create_positioner(int type,float x,float y,float w,float h,char label[])
/* creates an object */
{
FL_OBJECT *ob;
ob = fl_make_object(FL_POSITIONER,type,x,y,w,h,label,handle_positioner);
ob->boxtype = FL_POSITIONER_BOXTYPE;
ob->col1 = FL_POSITIONER_COL1;
ob->col2 = FL_POSITIONER_COL2;
ob->align = FL_POSITIONER_ALIGN;
ob->lcol = FL_POSITIONER_LCOL;
ob->spec = (int *) fl_malloc(sizeof(SPEC));
((SPEC *)(ob->spec))->xmin = 0.0;
((SPEC *)(ob->spec))->xmax = 1.0;
((SPEC *)(ob->spec))->xval = 0.5;
((SPEC *)(ob->spec))->ymin = 0.0;
((SPEC *)(ob->spec))->ymax = 1.0;
((SPEC *)(ob->spec))->yval = 0.5;
((SPEC *)(ob->spec))->xstep = 0.0;
((SPEC *)(ob->spec))->ystep = 0.0;
((SPEC *)(ob->spec))->always = TRUE;
return ob;
}
FL_OBJECT *fl_add_positioner(int type,float x,float y,float w,float h,char label[])
/* Adds an object */
{
FL_OBJECT *ob;
ob = fl_create_positioner(type,x,y,w,h,label);
fl_add_object(fl_current_form,ob);
return ob;
}
void fl_set_positioner_xvalue(FL_OBJECT *ob,float val)
{
((SPEC *)(ob->spec))->xval = val;
fl_redraw_object(ob);
}
void fl_set_positioner_yvalue(FL_OBJECT *ob,float val)
{
((SPEC *)(ob->spec))->yval = val;
fl_redraw_object(ob);
}
void fl_set_positioner_xbounds(FL_OBJECT *ob,float min,float max)
{
((SPEC *)(ob->spec))->xmin = min;
((SPEC *)(ob->spec))->xmax = max;
fl_redraw_object(ob);
}
void fl_set_positioner_ybounds(FL_OBJECT *ob,float min,float max)
{
((SPEC *)(ob->spec))->ymin = min;
((SPEC *)(ob->spec))->ymax = max;
fl_redraw_object(ob);
}
float fl_get_positioner_xvalue(FL_OBJECT *ob)
{ return ((SPEC *)(ob->spec))->xval; }
float fl_get_positioner_yvalue(FL_OBJECT *ob)
{ return ((SPEC *)(ob->spec))->yval; }
void fl_get_positioner_xbounds(FL_OBJECT *ob,float *min,float *max)
{
*min = ((SPEC *)(ob->spec))->xmin;
*max = ((SPEC *)(ob->spec))->xmax;
}
void fl_get_positioner_ybounds(FL_OBJECT *ob,float *min,float *max)
{
*min = ((SPEC *)(ob->spec))->ymin;
*max = ((SPEC *)(ob->spec))->ymax;
}
void fl_set_positioner_xstep(FL_OBJECT *ob, float value)
/* Sets the step size to which values are rounded. */
{ ((SPEC *)(ob->spec))->xstep = value; }
void fl_set_positioner_ystep(FL_OBJECT *ob, float value)
/* Sets the step size to which values are rounded. */
{ ((SPEC *)(ob->spec))->ystep = value; }
void fl_set_positioner_return(FL_OBJECT *ob, int value)
/* Sets whether to return value all the time */
{ ((SPEC *)(ob->spec))->always = value; }